package jorm;

import jorm.boneCplugin.BoneCPDataSourePlugin;
import jorm.c3p0Plugin.C3p0Plugin;
import jorm.DruidPlugin.DruidPlugin;
import jorm.dialect.Dialect;
import jorm.dialect.MysqlDialect;
import jorm.owner.Config;
import jorm.owner.ConfigFactory;
import com.jolbox.bonecp.BoneCPConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Properties;


/**
 * @auther:陈磊 <br/>
 * Date: 12-12-28<br/>
 * Time: 下午11:21<br/>
 * connectMethod:13638363871@163.com<br/>
 * 初始化orm，注册model
 * 初始化数据源；default :bonecp
 * Provider some plugin interface :druid c3p0
 */
public class  OrmProvider implements IOrmProvider {
    private static Logger LOGGER= LoggerFactory.getLogger(OrmProvider.class);
    private ActiveRecordPlugin activeRecordPlugin= null;
    private Class<? extends Config> dataSorceclazzConfig;
    private Class<? extends Config> ormMapperClazzConfig;
    private String poolType=""; //数据库连接池类型


    private Dialect dialect=new MysqlDialect();//default mysql


    public OrmProvider(Class<? extends Config> dataSorceclazzConfig,Class<? extends Config> ormMapperClazzConfig){
        this.dataSorceclazzConfig=dataSorceclazzConfig;
        this.ormMapperClazzConfig=ormMapperClazzConfig;
    }

    /**
     * 数据库连接池类型
     * @param poolType
     *        boneCp   druid c3p0
     */
    public void setPoolType(String poolType) {
       this.poolType=poolType;
    }

    /**
     * 初始化数据源
     */
    @Override
    public void IntiOrm(){
        try {
            Properties properties= ConfigFactory.loadPropertiesFor(this.dataSorceclazzConfig);
            this.setPoolType(properties.getProperty("poolType"));
            if(this.getDatasoruceTypeType().startsWith("b")){//boneCp
                BoneCPDataSourePlugin boneCPDataSourePlugin = new BoneCPDataSourePlugin(new BoneCPConfig(properties));
                activeRecordPlugin = new ActiveRecordPlugin(boneCPDataSourePlugin);
                activeRecordPlugin.setDialect(dialect);
                if(Boolean.valueOf(properties.getProperty("debug")))LOGGER.info("use the dataSourceType is "+this.getDatasoruceTypeType());
            }else if(this.getDatasoruceTypeType().startsWith("d")){ //druid
                DruidPlugin druidPlugin=new DruidPlugin(properties);
                druidPlugin.start();
                activeRecordPlugin = new ActiveRecordPlugin(druidPlugin);
                activeRecordPlugin.setDialect(dialect);
                if(Boolean.valueOf(properties.getProperty("debug")))LOGGER.info("use the dataSourceType is "+this.getDatasoruceTypeType());
            }else if(this.getDatasoruceTypeType().startsWith("c")){  //c3p0
                C3p0Plugin c3p0Plugin=new C3p0Plugin(properties);
                c3p0Plugin.start();
                activeRecordPlugin = new ActiveRecordPlugin(c3p0Plugin);
                activeRecordPlugin.setDialect(dialect);
                if(Boolean.valueOf(properties.getProperty("debug")))LOGGER.info("use the dataSourceType is "+this.getDatasoruceTypeType());
            }
            properties.clear();
        } catch (Exception e) {
            LOGGER.error("IntiOrm orm failed... ...",e);
        }
    }


    /**
     * 注册model orm
     *
     * @param tablename  model   对应的表名
     * @param primaryKey      主键ID
     * @param modelClass model  class
     */
    @Override
    public void RegisterModel(String tablename, String primaryKey, Class<? extends Model<?>> modelClass) {
        this.activeRecordPlugin.addMapping(tablename,primaryKey,modelClass);
        this.activeRecordPlugin.register();
    }

    /**
     * 注册model orm
     *
     * @param tablename  model   对应的表名  action： keyID is default id  ,
     *                   if not,please use the---> RegisterModel(String tablename,String keyID,Class<? extends Model<?>> modelClass);
     * @param modelClass modelclass
     */
    @Override
    public void RegisterModel(String tablename, Class<? extends Model<?>> modelClass) {
        this.activeRecordPlugin.addMapping(tablename,modelClass);
        this.activeRecordPlugin.register();
    }

    /**
     * 自动 注册model orm
     * 注意：使用此方法的时候，tableName 必须跟相应的model命名一样，可以不区分大小写
     */
    @Override
    @SuppressWarnings("unchecked")
    public void AutoRegisterModel(){
        try {
            Properties properties= ConfigFactory.loadPropertiesFor(this.ormMapperClazzConfig);
            String[] classNames = PackageUtils.findClassesInPackage(properties.getProperty("modelPackage"));
            for(Map.Entry<Object, Object> collections:properties.entrySet()){
                String  tableName= (String) collections.getKey();
                for (String classname:classNames){
                    String modelName=classname.substring(classname.lastIndexOf('.') + 1);
                    if (tableName.equalsIgnoreCase(modelName)) {
                        this.RegisterModel(tableName, (String) collections.getValue(),(Class<? extends Model<?>>)Class.forName(classname).newInstance().getClass());
                        break;
                    }
                }
            }
        }catch (Exception e){
           LOGGER.error("AutoRegisterModel  failed... ...",e);
        }

    }

    /**
     * 获取ActiveRecordPlugin
     *
     * @return
     */
    @Override
    @Deprecated
    public ActiveRecordPlugin getActiveRecordPlugin(){
        return this.activeRecordPlugin;  //To change body of implemented methods use File | Settings | File Templates.
    }

    /**
     * 打印sql语句
     */
    @Override
    public void showSql(boolean isprintln) {
        this.activeRecordPlugin.setShowSql(isprintln);
    }

    public String getDatasoruceTypeType() {
        return this.poolType;
    }

    public Dialect getDialect() {
        return dialect;
    }

    //配置数据库方言
    @Override
    public void setDialect(Dialect dialect) {
        this.dialect = dialect;
    }


}
